package nl.gertontenham.magnolia.templating.rendering.components;
import info.magnolia.dam.api.Asset;
import info.magnolia.dam.templating.functions.DamTemplatingFunctions;
import info.magnolia.jcr.util.PropertyUtil;
import info.magnolia.rendering.model.RenderingModel;
import info.magnolia.rendering.template.RenderableDefinition;
import info.magnolia.repository.RepositoryConstants;
import info.magnolia.util.EscapeUtil;
import nl.gertontenham.magnolia.templating.functions.FoundationTemplatingFunctions;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
/**
* Created by gtenham on 2015-08-28.
*/
public class LinkModel<RD extends RenderableDefinition> extends BaseComponentRenderableDefinition<RD> {
private static final Logger log = LoggerFactory.getLogger(LinkModel.class);
public static final String INTERNAL = "internal";
public static final String EXTERNAL = "external";
public static final String DOWNLOAD = "download";
public static final String PROPERTY_NAME_LINK_TYPE = "linkType";
public static final String PROPERTY_NAME_TITLE = "title";
public static final String PROPERTY_NAME_INTERNAL = PROPERTY_NAME_LINK_TYPE + INTERNAL;
public static final String PROPERTY_NAME_EXTERNAL = PROPERTY_NAME_LINK_TYPE + EXTERNAL;
public static final String PROPERTY_NAME_DOWNLOAD = PROPERTY_NAME_LINK_TYPE + DOWNLOAD;
private final DamTemplatingFunctions damTemplatingFunctions;
@Inject
public LinkModel(Node content, RD definition, RenderingModel<?> parent, FoundationTemplatingFunctions templatingFunctions, DamTemplatingFunctions damTemplatingFunctions) {
super(content, definition, parent, templatingFunctions);
this.damTemplatingFunctions = damTemplatingFunctions;
}
/**
* Returns the type of the link, {@link #INTERNAL}, {@link #EXTERNAL} or {@link #DOWNLOAD}.
*/
public String getLinkType() {
return PropertyUtil.getString(content, PROPERTY_NAME_LINK_TYPE, "");
}
/**
* Checks whether the link is an {@link #INTERNAL} link.
*/
public boolean isInternal() {
return INTERNAL.equals(getLinkType());
}
/**
* Checks whether the link is an {@link #EXTERNAL} link.
*/
public boolean isExternal() {
return EXTERNAL.equals(getLinkType());
}
/**
* Checks whether the link is a {@link #DOWNLOAD} link.
*/
public boolean isDownload() {
return DOWNLOAD.equals(getLinkType());
}
/**
* Get the title for the link based on the link type.
*
* @see #getLinkType()
*/
public String getTitle() {
if (isInternal()) {
return getInternalTitle();
} else if (isDownload()) {
return getDownloadTitle();
} else if (isExternal()) {
return getExternalTitle();
}
return "";
}
/**
* Get the download title by trying to determine the title of the {@link info.magnolia.dam.api.Asset}.
*/
protected String getDownloadTitle() {
String title = PropertyUtil.getString(content, PROPERTY_NAME_TITLE);
if (StringUtils.isBlank(title)) {
final Asset asset = getAsset();
if (asset != null) {
title = asset.getTitle();
if (StringUtils.isBlank(title)) {
title = asset.getFileName();
}
}
}
return title;
}
/**
* Get the title for an internal link by returning the first of the following items that are available
* <ul>
* <li>The title field of the component</li>
* <li>The title of the referenced page</li>
* <li>The node name of the referenced page</li>
* </ul>.
*/
protected String getInternalTitle() {
final String title = PropertyUtil.getString(content, PROPERTY_NAME_TITLE);
if (StringUtils.isNotBlank(title)) {
return title;
}
try {
final Node linkedNode = templatingFunctions.contentByReference(content, PROPERTY_NAME_INTERNAL, RepositoryConstants.WEBSITE);
final String pageTitle = PropertyUtil.getString(linkedNode, PROPERTY_NAME_TITLE, "");
if (StringUtils.isNotBlank(pageTitle)) {
return pageTitle;
}
return linkedNode.getName();
} catch (RepositoryException e) {
log.warn("An error occurred when trying to get referenced content for node [{}] and property [{}]", content, PROPERTY_NAME_INTERNAL, e);
}
return "";
}
/**
* Get the title for an external link.
*
* @see info.magnolia.templating.functions.TemplatingFunctions#externalLinkTitle(Node, String, String)
*/
protected String getExternalTitle() {
final String title = templatingFunctions.externalLinkTitle(content, PROPERTY_NAME_EXTERNAL, PROPERTY_NAME_TITLE);
return EscapeUtil.escapeXss(title);
}
/**
* Get the url for the link based on the linkType.
*/
public String getLink() {
if (isInternal()) {
return getInternalLink();
} else if (isDownload()) {
return getDownloadLink();
} else if (isExternal()) {
return getExternalLink();
}
return "";
}
/**
* Get the internal link by using the stored identifier to resolve the referenced {@link Node} and linking to it.
* Limited to workspace {@link RepositoryConstants#WEBSITE} only.
*
* @see info.magnolia.templating.functions.TemplatingFunctions#link(String, String)
*/
protected String getInternalLink() {
return templatingFunctions.link(RepositoryConstants.WEBSITE, PropertyUtil.getString(content, PROPERTY_NAME_INTERNAL));
}
/**
* Get the external link. Anchors starting with <code>#</code> are returned as is.
*
* @see info.magnolia.templating.functions.TemplatingFunctions#externalLink(Node, String)
*/
protected String getExternalLink() {
final String linkRaw = PropertyUtil.getString(content, PROPERTY_NAME_EXTERNAL);
if (StringUtils.startsWith(linkRaw, "#")) {
return EscapeUtil.escapeXss(linkRaw);
}
final String link = templatingFunctions.externalLink(content, PROPERTY_NAME_EXTERNAL);
return EscapeUtil.escapeXss(link);
}
/**
* Get the link to a downloadable {@link Asset}.
*
* @see #getAsset()
*/
protected String getDownloadLink() {
final Asset asset = getAsset();
if (asset != null) {
return asset.getLink();
}
return null;
}
/**
* Retrieve the Asset referenced by the identifier stored into the 'link'
* properties.
*/
public Asset getAsset() {
final String assetIdentifier = PropertyUtil.getString(content, PROPERTY_NAME_DOWNLOAD);
if (StringUtils.isNotBlank(assetIdentifier)) {
return damTemplatingFunctions.getAsset(assetIdentifier);
}
return null;
}
}